#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h" // Needed to enable switch 1
#include "inc/hw_sysctl.h" // Needed to enable switch 1
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"

#define LED_RED GPIO_PIN_1
#define LED_BLUE GPIO_PIN_2
#define LED_GREEN GPIO_PIN_3

#define BUTTON_1 GPIO_PIN_0
#define BUTTON_2 GPIO_PIN_4


int buttonHeld = 0;


/////// Used for task #4
void SwitchIntHandler(void)
{
	// Clear the timer interrupt
	GPIOIntClear(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);

	// Read the current state of the GPIO pin and
	// write back the opposite state

		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
		buttonHeld =! buttonHeld;


}












int main(void)
{
	uint32_t ui32Period;

	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); /// Running at 40MHZ

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //// Enable the portF.
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);// Enable the Pins 1-3 on portF

	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // Enables the 
	TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

	ui32Period = (SysCtlClockGet() / 10) / 2; // Original code. This is the frequency. /10 /2, means 20 interrupts, but a frequency cycle is high to low, then low to high, which requires 2 interrupts, which is 10 HZ.
	//ui32Period = (SysCtlClockGet() / 30) / 2; //Task #02 Setting it to /30 / 2, gives 30HZ with 50% duty (equal).
	TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);

	IntEnable(INT_TIMER0A); /// Enables the specific vector of timer0A
	TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // Enables the interrupt when it has TIMEOUT which generates the interrupt
	IntMasterEnable(); ////// Enables the master interrupt

	TimerEnable(TIMER0_BASE, TIMER_A); /// Enable Timer 0A.



    // set LED pins as outputs
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN);



    // set user switches as inputs
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);
    GPIOIntEnable(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2);
    GPIOIntRegister(GPIO_PORTF_BASE, SwitchIntHandler);

    // turn weak pull-ups on
    GPIOPadConfigSet(GPIO_PORTF_BASE, BUTTON_1|BUTTON_2, GPIO_STRENGTH_2MA,
    GPIO_PIN_TYPE_STD_WPU);



	while(1)
	{
	}
}


uint32_t freqChange = 1;


void Timer0IntHandler(void)
{




	////// Task 03
	///// Below changes the frqeuency of a 10Hz period.
	/*
	uint32_t ui32Period = (SysCtlClockGet() / 10) / 2 *freqChange;
	TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period -1);
	if(freqChange==10) freqChange = 1;
	freqChange++;
*/

	if(buttonHeld==0){
	// Clear the timer interrupt
	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

	// Read the current state of the GPIO pin and
	// write back the opposite state
	if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
	{
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
	}
	else
	{
		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
	}

	}
}









